﻿using System;
using System.Linq;
using Urs.Data.Domain.Orders;

namespace Urs.Services.Orders
{
    public static class OrderExtensions
    {
        public static string FormatOrderNoteText(this OrderNote orderNote)
        {
            if (orderNote == null)
                throw new ArgumentNullException("orderNote");

            string text = orderNote.Note;

            if (String.IsNullOrEmpty(text))
                return string.Empty;

            text = Urs.Core.Html.HtmlHelper.FormatText(text, false, true, false, false, false, false);

            return text;
        }

        public static int GetTotalNumberOfItemsInAllShipment(this OrderItem opv)
        {
            if (opv == null)
                throw new ArgumentNullException("opv");

            var totalInShipments = 0;
            var shipments = opv.Order.Shipments.ToList();
            for (int i = 0; i < shipments.Count; i++)
            {
                var shipment = shipments[i];
                var sopv = shipment.ShipmentorderItems
                    .Where(x => x.OrderItemId == opv.Id)
                    .FirstOrDefault();
                if (sopv != null)
                {
                    totalInShipments += sopv.Quantity;
                }
            }
            return totalInShipments;
        }

        public static int GetTotalNumberOfItemsCanBeAddedToShipment(this OrderItem opv)
        {
            if (opv == null)
                throw new ArgumentNullException("opv");

            var totalInShipments = opv.GetTotalNumberOfItemsInAllShipment();

            var qtyOrdered = opv.Quantity;
            var qtyCanBeAddedToShipmentTotal = qtyOrdered - totalInShipments;
            if (qtyCanBeAddedToShipmentTotal < 0)
                qtyCanBeAddedToShipmentTotal = 0;

            return qtyCanBeAddedToShipmentTotal;
        }

        public static int GetTotalNumberOfNotYetShippedItems(this OrderItem opv)
        {
            if (opv == null)
                throw new ArgumentNullException("opv");

            var result = 0;
            var shipments = opv.Order.Shipments.ToList();
            for (int i = 0; i < shipments.Count; i++)
            {
                var shipment = shipments[i];
                if (shipment.ShippedTime.HasValue)
                    continue;

                var sopv = shipment.ShipmentorderItems
                    .Where(x => x.OrderItemId == opv.Id)
                    .FirstOrDefault();
                if (sopv != null)
                {
                    result += sopv.Quantity;
                }
            }

            return result;
        }

        public static int GetTotalNumberOfShippedItems(this OrderItem opv)
        {
            if (opv == null)
                throw new ArgumentNullException("opv");

            var result = 0;
            var shipments = opv.Order.Shipments.ToList();
            for (int i = 0; i < shipments.Count; i++)
            {
                var shipment = shipments[i];
                if (!shipment.ShippedTime.HasValue)
                    continue;

                var sopv = shipment.ShipmentorderItems
                    .Where(x => x.OrderItemId == opv.Id)
                    .FirstOrDefault();
                if (sopv != null)
                {
                    result += sopv.Quantity;
                }
            }
            
            return result;
        }

        public static int GetTotalNumberOfDeliveredItems(this OrderItem opv)
        {
            if (opv == null)
                throw new ArgumentNullException("opv");

            var result = 0;
            var shipments = opv.Order.Shipments.ToList();
            for (int i = 0; i < shipments.Count; i++)
            {
                var shipment = shipments[i];
                if (!shipment.DeliveryTime.HasValue)
                    continue;

                var sopv = shipment.ShipmentorderItems
                    .Where(x => x.OrderItemId == opv.Id)
                    .FirstOrDefault();
                if (sopv != null)
                {
                    result += sopv.Quantity;
                }
            }

            return result;
        }



        public static bool HasItemsToAddToShipment(this Order order)
        {
            if (order == null)
                throw new ArgumentNullException("order");

            foreach (var opv in order.orderItems)
            {
                if (!opv.Goods.IsShipEnabled)
                    continue;

                var totalNumberOfItemsCanBeAddedToShipment = opv.GetTotalNumberOfItemsCanBeAddedToShipment();
                if (totalNumberOfItemsCanBeAddedToShipment <= 0)
                    continue;

                return true;
            }
            return false;
        }
        public static bool HasItemsToShip(this Order order)
        {
            if (order == null)
                throw new ArgumentNullException("order");

            foreach (var opv in order.orderItems)
            {
                if (!opv.Goods.IsShipEnabled)
                    continue;

                var totalNumberOfNotYetShippedItems = opv.GetTotalNumberOfNotYetShippedItems();
                if (totalNumberOfNotYetShippedItems <= 0)
                    continue;

                return true;
            }
            return false;
        }
        public static bool HasItemsToDeliver(this Order order)
        {
            if (order == null)
                throw new ArgumentNullException("order");

            foreach (var opv in order.orderItems)
            {
                if (!opv.Goods.IsShipEnabled)
                    continue;

                var totalNumberOfShippedItems = opv.GetTotalNumberOfShippedItems();
                var totalNumberOfDeliveredItems = opv.GetTotalNumberOfDeliveredItems();
                if (totalNumberOfShippedItems <= totalNumberOfDeliveredItems)
                    continue;

                return true;
            }
            return false;
        }
    }
}
